package com.xyy.dfapi.helper;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdcardUtil;
import com.google.common.collect.Lists;
import com.xyy.dfapi.enums.CustomerTypeEnum;
import com.xyy.dfapi.enums.QualificationEnum;
import com.xyy.dfapi.pojo.*;
import com.xyy.dfapi.utils.DateUtils;
import org.jetbrains.annotations.NotNull;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static java.math.BigDecimal.ZERO;

public class ErpHelper {

    private static final String FORDATE = "yyyy-MM-dd";

    public static List<PopErpSkuForInsertDto> convertErpToPopSkuDtos(List<ErpGoodsDto> erpGoodsDtoList, List<ErpGoodsStockDto> erpGoodsStockDtoList) {
        if (erpGoodsDtoList.isEmpty() || erpGoodsStockDtoList.isEmpty()) {
            return Lists.newArrayList();
        }
        List<PopErpSkuForInsertDto> popErpSkuForInsertDtoList = Lists.newArrayList();

        Map<String, List<ErpGoodsStockDto>> goodStockMap = erpGoodsStockDtoList.stream().filter(m -> m.getBgmCode() != null).collect(Collectors.groupingBy(m -> m.getBgmCode()));
        for (ErpGoodsDto erpGoodsDto : erpGoodsDtoList) {
            List<ErpGoodsStockDto> erpGoodsStockDtos = goodStockMap.get(erpGoodsDto.getBgmCode());
            if (CollectionUtil.isEmpty(erpGoodsStockDtos)) {
                continue;
            }
            BigDecimal stockTotal = erpGoodsStockDtos.stream().map(m -> m.getNum()).filter(Objects::nonNull).reduce(ZERO, BigDecimal::add);
            if (stockTotal.compareTo(ZERO) <= 0) {
                continue;
            }
            popErpSkuForInsertDtoList.add(convertProductFullInfo(erpGoodsDto, erpGoodsStockDtos));
        }
        return popErpSkuForInsertDtoList;
    }

    private static PopErpSkuForInsertDto convertProductFullInfo(ErpGoodsDto erpGoodsDto, List<ErpGoodsStockDto> erpGoodsStockDtos) {
        PopErpSkuForInsertDto popSku = new PopErpSkuForInsertDto();
        popSku.setErpCode(erpGoodsDto.getBgmCode());
        popSku.setProductName(erpGoodsDto.getBgmName());
        popSku.setCommonName(erpGoodsDto.getBgmName());
        popSku.setApprovalNumber(erpGoodsDto.getBgiAppnumber());
        popSku.setCode(erpGoodsDto.getBarcode());
        popSku.setManufacturer(erpGoodsDto.getManufacturer());
        popSku.setMediumPackageNum(1);
        popSku.setProductUnit(erpGoodsDto.getBgpUnitmeasurement());
        popSku.setSpec(erpGoodsDto.getSpec());
        popSku.setDosageForm(erpGoodsDto.getBgiProrangeName());
        popSku.setTerm("36");
        popSku.setSuggestPrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
        popSku.setProductionArea(erpGoodsDto.getPlaceorigin());
        popSku.setMonomerPrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
        popSku.setBasePrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
        popSku.setChainPrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
        BigDecimal stockTotal = erpGoodsStockDtos.stream().map(m -> m.getNum()).filter(Objects::nonNull).reduce(ZERO, BigDecimal::add);
        String oldestProDate = erpGoodsStockDtos.stream().map(m -> m.getProdate()).filter(Objects::nonNull).min(String::compareTo).orElse(null);
        String newProDate = erpGoodsStockDtos.stream().map(m -> m.getProdate()).filter(Objects::nonNull).max(String::compareTo).orElse(null);
        String nearEffect = erpGoodsStockDtos.stream().map(m -> m.getExpidate()).filter(Objects::nonNull).min(String::compareTo).orElse(null);
        String farEffect = erpGoodsStockDtos.stream().map(m -> m.getExpidate()).filter(Objects::nonNull).max(String::compareTo).orElse(null);
        popSku.setAvailableQyt(stockTotal.intValue());
        popSku.setOldestProDate(oldestProDate);
        popSku.setNewProDate(newProDate);
        popSku.setNearEffect(nearEffect);
        popSku.setFarEffect(farEffect);
        popSku.setMarketAuthor(erpGoodsDto.getBgiRegistno());
        return popSku;
    }

    public static List<PopErpSkuStockV2Dto> convertErpToPopSkuStock(List<ErpGoodsStockDto> erpGoodsStockDtoList) {
        Map<String, List<ErpGoodsStockDto>> stockList = erpGoodsStockDtoList.stream().collect(Collectors.groupingBy(m -> m.getBgmCode()));
        List<PopErpSkuStockV2Dto> popErpSkuStockV2DtoList = new ArrayList<>();
        for (Map.Entry<String, List<ErpGoodsStockDto>> entry : stockList.entrySet()) {
            popErpSkuStockV2DtoList.add(convertErpToPopSkuStockHelp(entry.getKey(), entry.getValue()));
        }
        return popErpSkuStockV2DtoList;
    }

    private static PopErpSkuStockV2Dto convertErpToPopSkuStockHelp(String key, List<ErpGoodsStockDto> erpGoodsStockDtos) {
        PopErpSkuStockV2Dto popErpSkuStockV2Dto = new PopErpSkuStockV2Dto();
        popErpSkuStockV2Dto.setErpCode(key);
        BigDecimal stockTotal = erpGoodsStockDtos.stream().map(ErpGoodsStockDto::getNum).filter(Objects::nonNull).reduce(ZERO, BigDecimal::add);
        if (stockTotal.compareTo(ZERO) <= 0) {
            return new PopErpSkuStockV2Dto();
        }
        String oldestProDate = erpGoodsStockDtos.stream().map(ErpGoodsStockDto::getProdate).filter(Objects::nonNull).min(String::compareTo).orElse(null);
        String newProDate = erpGoodsStockDtos.stream().map(ErpGoodsStockDto::getProdate).filter(Objects::nonNull).max(String::compareTo).orElse(null);
        String nearEffect = erpGoodsStockDtos.stream().map(ErpGoodsStockDto::getExpidate).filter(Objects::nonNull).min(String::compareTo).orElse(null);
        String farEffect = erpGoodsStockDtos.stream().map(ErpGoodsStockDto::getExpidate).filter(Objects::nonNull).max(String::compareTo).orElse(null);
        popErpSkuStockV2Dto.setOldestProDate(oldestProDate);
        popErpSkuStockV2Dto.setNewProDate(newProDate);
        popErpSkuStockV2Dto.setNearEffect(nearEffect);
        popErpSkuStockV2Dto.setFarEffect(farEffect);
        popErpSkuStockV2Dto.setAvailableQyt(stockTotal.intValue());
        return popErpSkuStockV2Dto;
    }


    public static List<PopErpSkuPriceDto> convertErpToPopSkuPrice(List<ErpGoodsDto> erpGoodsDtoList) {
        List<PopErpSkuPriceDto> popErpSkuPriceDtoList = new ArrayList<>();
        for (ErpGoodsDto erpGoodsDto : erpGoodsDtoList) {
            if (erpGoodsDto.getSuggestePrice() <= 0) {
                continue;
            }
            PopErpSkuPriceDto popErpSkuPriceDto = new PopErpSkuPriceDto();
            popErpSkuPriceDto.setErpCode(erpGoodsDto.getBgmCode());
            popErpSkuPriceDto.setMonomerPrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
            popErpSkuPriceDto.setChainPrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
            popErpSkuPriceDto.setBasePrice(BigDecimal.valueOf(erpGoodsDto.getSuggestePrice()));
            popErpSkuPriceDtoList.add(popErpSkuPriceDto);
        }
        return popErpSkuPriceDtoList;
    }

    public static List<PopErpClientInfoDto> convertErpToPopCustomer(List<ErpCustDto> erpCustDtoList) {
        List<PopErpClientInfoDto> popErpClientInfoDtos = new ArrayList<>();
        for (ErpCustDto erpCustDto : erpCustDtoList) {
            PopErpClientInfoDto popErpClientInfoDto = new PopErpClientInfoDto();
            popErpClientInfoDto.setCustomerId(erpCustDto.getCmCode());
            popErpClientInfoDto.setCustomerCode(erpCustDto.getCmCode());
            popErpClientInfoDto.setCustomerName(erpCustDto.getCmName().trim());
            popErpClientInfoDtos.add(popErpClientInfoDto);
        }
        return popErpClientInfoDtos;
    }

    public static ErpInsertCustomerDto convertPopToErpCustomer(PlatformCustomerDto popCust) {
        ErpInsertCustomerDto erpInsertCustomerDto = new ErpInsertCustomerDto();
        erpInsertCustomerDto.setUnitNum(String.valueOf(popCust.getMerchantId()));
        erpInsertCustomerDto.setCmName(popCust.getCustomerName());
        // 客户类型
        erpInsertCustomerDto.setCmIntype(CustomerTypeEnum.fromTypeCode(popCust.getType()).getDescription());
        erpInsertCustomerDto.setCmLegalperson(popCust.getLegalPerson());
        erpInsertCustomerDto.setCmSocialcode(popCust.getTaxpayerIdentity());
        erpInsertCustomerDto.setCmPhone(popCust.getPickPhone());
        erpInsertCustomerDto.setCaiLinker(popCust.getPickName());
        erpInsertCustomerDto.setCaiProvince(popCust.getProvinceName());
        erpInsertCustomerDto.setCaiCity(popCust.getCityName());
        erpInsertCustomerDto.setCaiArea(popCust.getCountryName());
        erpInsertCustomerDto.setCmRegaddres(popCust.getRegisteredAddress());
        erpInsertCustomerDto.setCmWareaddress(popCust.getPickAddress());
        erpInsertCustomerDto.setCmBank(popCust.getRegisteredBank());
        erpInsertCustomerDto.setCmBankaccount(popCust.getRegisteredBankAccount());
        erpInsertCustomerDto.setMpMuCuslicenceannAdds(convertErpCustomerqua(popCust));
        erpInsertCustomerDto.setMpMuSalesAdds(convertErpCustomerEmp(popCust));
        return erpInsertCustomerDto;
    }

    /**
     * 客户业务员信息
     *
     * @param popCust 客户信息
     * @return 业务员信息
     */
    private static List<CustomerEmpDtp> convertErpCustomerEmp(PlatformCustomerDto popCust) {
        List<CustomerEmpDtp> empDtpList = new ArrayList<>();

        // 采购委托书
        CustomerEmpDtp cgWts = new CustomerEmpDtp();
        cgWts.setSalesName(popCust.getClientName());
        cgWts.setPhone(popCust.getPickPhone());
        cgWts.setNumberValidity(DateUtils.format(popCust.getClientCardExpireDate(), FORDATE));
        cgWts.setSalesNumber(popCust.getClientCardNo());
        cgWts.setSalesSex(IdcardUtil.getGenderByIdCard(popCust.getClientCardNo()) == 1 ? "男" : "女");
        cgWts.setPuTerValidity(DateUtils.format(popCust.getClientExpireDate(), FORDATE));
        cgWts.setReTerValidity(DateUtils.format(popCust.getClientExpireDate(), FORDATE));
        cgWts.setPuTerPath(popCust.getClientUrl());
        cgWts.setReTerPath(popCust.getClientUrl());
        cgWts.setCardPath(popCust.getClientCardUrl());
        empDtpList.add(cgWts);
        return empDtpList;
    }

    /**
     * 资质信息
     *
     * @param popCust pop客户
     * @return erp资质信息
     */
    private static List<CustomerQualificationDto> convertErpCustomerqua(PlatformCustomerDto popCust) {
        List<CustomerQualificationDto> zzXxList = new ArrayList<>();
        CustomerQualificationDto yyzz = new CustomerQualificationDto();
        if (popCust.getBusinessLicenseNumber() != null) {
            // 营业执照
            yyzz.setCliTername(QualificationEnum.YYZZ.getName());
            yyzz.setCliTernumber(popCust.getBusinessLicenseNumber());
            yyzz.setCliTervalidity(DateUtils.format(popCust.getBusinessLicenseExpireDate(), FORDATE));
            yyzz.setLityId(QualificationEnum.YYZZ.getName());
            yyzz.setCliOldurl(popCust.getBusinessLicenseUrl());
            zzXxList.add(yyzz);
        }
        // 食品经营许可证
        CustomerQualificationDto foodZz = new CustomerQualificationDto();
        if (popCust.getFoodBusitcardNo() != null) {
            foodZz.setCliTername(QualificationEnum.SPJYXK.getName());
            foodZz.setCliTernumber(popCust.getFoodBusitcardNo());
            foodZz.setCliTervalidity(DateUtils.format(popCust.getFoodBusitcardExpireDate(), FORDATE));
            foodZz.setLityId(QualificationEnum.SPJYXK.getName());
            foodZz.setCliOldurl(popCust.getFoodBusitcardUrl());
            zzXxList.add(foodZz);
        }
        CustomerQualificationDto xkz = new CustomerQualificationDto();
        if (popCust.getPermitNumber() != null) {
            if (popCust.getMedicalInsOccNo() != null) {
                // 医疗机构职业许可证
                xkz.setCliTername(QualificationEnum.YLJG.getName());
                xkz.setCliTernumber(popCust.getMedicalInsOccNo());
                xkz.setCliTervalidity(DateUtils.format(popCust.getMedicalInsOccExpireDate(), FORDATE));
                xkz.setLityId(QualificationEnum.YLJG.getName());
                xkz.setCliOldurl(popCust.getMedicalInsOccUrl());
                zzXxList.add(xkz);
            } else {
                // 药品经营许可证
                xkz.setCliTername(QualificationEnum.YPJYXK.getName());
                xkz.setCliTernumber(popCust.getDrugBusNo());
                xkz.setCliTervalidity(DateUtils.format(popCust.getDrugBusExpireDate(), FORDATE));
                xkz.setLityId(QualificationEnum.YPJYXK.getName());
                xkz.setCliOldurl(popCust.getDrugBusUrl());
                zzXxList.add(xkz);
            }
        }
        // 医疗器械二类备案
        CustomerQualificationDto erlqxZz = new CustomerQualificationDto();
        if (popCust.getClassIIMedicalDeviceNo() != null) {
            erlqxZz.setCliTername(QualificationEnum.YLQXEL.getName());
            erlqxZz.setCliTernumber(popCust.getClassIIMedicalDeviceNo());
            erlqxZz.setCliTervalidity(DateUtils.format(popCust.getClassIIMedicalDeviceExpireDate(), FORDATE));
            erlqxZz.setLityId(QualificationEnum.YLQXEL.getName());
            erlqxZz.setCliOldurl(popCust.getClassIIMedicalUrl());
            zzXxList.add(erlqxZz);
        }
        return zzXxList;
    }

    /**
     * @param popOrder pop订单
     * @return erp订单
     */

    public static ErpInsertOrderDto convertPopToErpOrder(SellerOrderInfoDto popOrder) {
        // 发票信息
        SellerOrderInvoiceDto sellerOrderInvoice = popOrder.getSellerOrderInvoice();
        // 订单明细
        List<SellerOrderDetailDto> sellerOrderDetailLists = popOrder.getSellerOrderDetailLists();
        ErpInsertOrderDto erpOrder = new ErpInsertOrderDto();
        erpOrder.setBillType(sellerOrderInvoice.getType() == 1 || sellerOrderInvoice.getType() == 3 ? "普票" : "专票");
        erpOrder.setCityName(popOrder.getCityName());
        erpOrder.setCmCode(popOrder.getVenderCode());
        erpOrder.setUnitNum(String.valueOf(popOrder.getMerchantId()));
        erpOrder.setCorOrderCode(popOrder.getOrderNo());
        erpOrder.setDistrictName(popOrder.getAreaName());
        erpOrder.setOrderCode(popOrder.getOrderNo());
        erpOrder.setOrderDate(DateUtils.format(popOrder.getOrderCreateTime(), FORDATE));
        erpOrder.setOrderTime(DateUtils.format(popOrder.getOrderCreateTime(), "HH:mm:ss"));
        erpOrder.setProvinceName(popOrder.getProvinceName());
        erpOrder.setReceiveAddress(popOrder.getPickAddress());
        erpOrder.setRecvName(popOrder.getPickName());
        erpOrder.setRecvPhone(popOrder.getPickPhone());
        erpOrder.setRemark("【药帮忙】-" + popOrder.getOrderNo() + popOrder.getRemark());
        erpOrder.setStreetName(popOrder.getPickAddress());
        erpOrder.setTotalMoney(String.valueOf(popOrder.getTotalAmount()));
        List<ErpOrderDetailDto> erpOrderDetailDtoList = new ArrayList<>();
        for (SellerOrderDetailDto popOrderMx : sellerOrderDetailLists) {
            ErpOrderDetailDto erpOrderMx = getErpOrderDetailDto(popOrderMx);
            erpOrderDetailDtoList.add(erpOrderMx);
        }
        erpOrder.setDetailList(erpOrderDetailDtoList);
        return erpOrder;
    }

    @NotNull
    private static ErpOrderDetailDto getErpOrderDetailDto(SellerOrderDetailDto popOrderMx) {
        ErpOrderDetailDto erpOrderMx = new ErpOrderDetailDto();
        erpOrderMx.setBgmCode(popOrderMx.getErpCode());
        erpOrderMx.setNum(popOrderMx.getPurchaseNumDecimal());
        erpOrderMx.setOrderCode(popOrderMx.getOrderNo());
        erpOrderMx.setPsmoney(popOrderMx.getPurchaseNumDecimal().multiply(popOrderMx.getSkuPayPrice()));
        erpOrderMx.setPsprice(popOrderMx.getSkuPayPrice());
        erpOrderMx.setRowno(String.valueOf(popOrderMx.getOrderDetailId()));
        erpOrderMx.setOrderDetailId(String.valueOf(popOrderMx.getOrderDetailId()));
        return erpOrderMx;
    }

    public static List<SellerOrderDeliverDetailForErpDto> convertErpToPopOrderOutDetail(ErpOrderStateDto erpOrderStateDto) {
        List<SellerOrderDeliverDetailForErpDto> detailForErpDtos = new ArrayList<>();
        List<ErpOrderOutDetailDto> orderDetailVoList = erpOrderStateDto.getOrderDetailVoList();
        for (ErpOrderOutDetailDto erpOrderOutDetailDto : orderDetailVoList) {
            SellerOrderDeliverDetailForErpDto orderMx = new SellerOrderDeliverDetailForErpDto();
            orderMx.setOrderNo(erpOrderStateDto.getCorOrderCode());
            orderMx.setOrderDetailId(Long.valueOf(erpOrderOutDetailDto.getOrderDetailId()));
            orderMx.setErpCode(erpOrderOutDetailDto.getBgmCode());
            orderMx.setBatchCode(erpOrderOutDetailDto.getBatchno());
            orderMx.setBatchNumDecimal(erpOrderOutDetailDto.getNum());
            orderMx.setBatchValidDate(erpOrderOutDetailDto.getExpidate());
            orderMx.setProductionDate(erpOrderOutDetailDto.getProdate());
            orderMx.setBatchPrice(erpOrderOutDetailDto.getPsprice());
            detailForErpDtos.add(orderMx);
        }
        return detailForErpDtos;
    }

    public static SellerOrderDeliverInfoDto convertErpToPopOrderDeliver(ErpOrderStateDto erpOrderStateDto, String orgId) {
        SellerOrderDeliverInfoDto sellerOrderDeliverInfoDto = new SellerOrderDeliverInfoDto();
        sellerOrderDeliverInfoDto.setOrgId(orgId);
        sellerOrderDeliverInfoDto.setOrderNo(erpOrderStateDto.getCorOrderCode());
        sellerOrderDeliverInfoDto.setLogiNo(convertWlNo(erpOrderStateDto.getLogisticsName(), 1));
        sellerOrderDeliverInfoDto.setLogiCompany(convertWlNo(erpOrderStateDto.getLogisticsName(), 2));
        sellerOrderDeliverInfoDto.setDeliveryId(erpOrderStateDto.getLogisticsNo());
        return sellerOrderDeliverInfoDto;
    }

    private static String convertWlNo(String logisticsId, int type) {

        String result;
        switch (logisticsId) {
            case "京东快运":
                if (type == 1) {
                    result = "11";
                } else {
                    result = "京东物流";
                }
                break;
            case "京东快递":
                if (type == 1) {
                    result = "31";
                } else {
                    result = "京东快递";
                }
                break;
            default:
                if (type == 1) {
                    result = "20";
                } else {
                    result = "其他物流公司";
                }
        }
        return result;
    }

    public static PopErpInvoiceDto convertErpToPopOrderInvoice(ErpOrderInvoiceDto erpOrderInvoiceDto) {
        PopErpInvoiceDto popErpInvoiceDto = new PopErpInvoiceDto();
        popErpInvoiceDto.setOrderNo(erpOrderInvoiceDto.getCorOrderCode());
        popErpInvoiceDto.setOrderInvoiceUrl(erpOrderInvoiceDto.getPdfUrl());
        return popErpInvoiceDto;
    }

    public static PopErpOrderCompleteDto convertErpToPopOrderDone(ErpOrderStateDto erpOrderStateDto) {
        PopErpOrderCompleteDto popErpOrderCompleteDto = new PopErpOrderCompleteDto();
        popErpOrderCompleteDto.setOrderNo(erpOrderStateDto.getCorOrderCode());
        popErpOrderCompleteDto.setSortingTime(LocalDateTime.now());
        return popErpOrderCompleteDto;
    }

}